package org.tinygroup.menuframe.util;


import org.tinygroup.menuframe.config.Menu;
import org.tinygroup.menuframe.dto.MenuNode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by wangwy11342 on 2016/7/29.
 */
public class MenuUtil {
    public MenuNode[] toTree(Integer[] menuIds,
                             Menu[] menus) {
        if (menuIds == null) {
            return new MenuNode[0];
        }
        // 存放所有的权限菜单
        Map<Integer, MenuNode> nodeMap = new HashMap<Integer, MenuNode>();
        for (Menu tsysMenu : menus) {
            MenuNode node = new MenuNode(tsysMenu.getId(), tsysMenu);
            nodeMap.put(node.getId(), node);
        }
        // 存放已计算过的节点Id
        List<Integer> computedIds = new ArrayList<Integer>();
        // 存放已计算过的节点
        Map<Integer, MenuNode> computedNodes = new HashMap<Integer, MenuNode>();
        for (Integer menuId : menuIds) {
            if(!nodeMap.containsKey(menuId)){
                //所有菜单中不包含的菜单被排除
                continue;
            }
            MenuNode node = nodeMap.get(menuId);
//            MenuNode node = new MenuNode(userMenu.getId(), userMenu);
            computed(node, computedIds, computedNodes, nodeMap);
        }
        return toArray(computedNodes);
    }

    protected MenuNode[] toArray(Map<Integer, MenuNode> computedNodes) {
        List<MenuNode> list = new ArrayList<MenuNode>();
        for (MenuNode node : computedNodes.values()) {
            Menu tsysMenu = (Menu) node.getInfo();
            if (tsysMenu.getParentId()==null || tsysMenu.getParentId() == 0) {
                list.add(node);
                continue;
            }
        }
        MenuNode[] tree = new MenuNode[list.size()];
        int i = 0;
        for (MenuNode node : list) {
            tree[i] = node;
            i++;
        }
        return tree;
    }

    protected void computed(MenuNode node, List<Integer> computedIds,
                            Map<Integer, MenuNode> computedNodes, Map<Integer, MenuNode> nodeMap) {
        Integer id = node.getId();
        if (computedNodes.containsKey(id)) {
            return;
        }
        // 如果没算过，就把他存放到已算列表
        computedNodes.put(id, node);
        computedIds.add(id);
        // 然后计算该节点的父节点
        Menu tsysMenu = (Menu) node.getInfo();
        Integer parentId  = null;
        if(tsysMenu.getParentId()!=null && tsysMenu.getParentId()!=0){
            parentId = Integer.valueOf(tsysMenu.getParentId());
        }
        if (parentId == null || parentId==0) {
            return;
        }
        Menu parent = (Menu) nodeMap.get(parentId).getInfo();
        MenuNode nodeParent = computedNodes.get(parentId);
        if (nodeParent == null) {
            nodeParent = new MenuNode(parentId, parent);
        }
        nodeParent.getSubNode().add(node);

        computed(nodeParent, computedIds, computedNodes, nodeMap);

    }

    public MenuNode[] toTreeByList(List<Integer> tUserTFunctionIds, List<Menu> tFunctions){
        Integer[] userFunctionIdArray = new Integer[tUserTFunctionIds!=null?tUserTFunctionIds.size():0];
        Menu[] tFunctionArray = new Menu[tFunctions!=null?tFunctions.size():0];
        tUserTFunctionIds.toArray(userFunctionIdArray);
        tFunctions.toArray(tFunctionArray);
        return toTree(userFunctionIdArray , tFunctionArray);
    }

    public void getSelectedPath(List<MenuNode> treeNodes, String currentUrl,
                                List<Integer> pathList){
        Map<Integer,Integer> fetchMap = new HashMap<Integer, Integer>();
        Integer selId = fetch(treeNodes,currentUrl,fetchMap);
        if(selId==null) {
            fetchDefaultPath(treeNodes,pathList);
        }else {
            getPath(fetchMap, pathList, selId);
        }
    }

    private void fetchDefaultPath(List<MenuNode> treeNodes, List<Integer> pathList) {
        List<MenuNode> curTreeNodes = treeNodes;
        while(curTreeNodes.size()>0){
            MenuNode treeNode = curTreeNodes.get(0);
            pathList.add(treeNode.getId());
            curTreeNodes = treeNode.getSubNode();
        }
    }

    private void getPath(Map<Integer, Integer> fetchMap,List<Integer> pathList, Integer selId) {
        if(selId==null || selId==0){
            return;
        }
        pathList.add(selId);
        Integer pid = fetchMap.get(selId);
        //迭代获取path
        while(pid!=null && pid!=0){
            pathList.add(0,pid);
            pid = fetchMap.get(pid);
        }
    }

    private Integer fetch(List<MenuNode> treeNodes, String currentUrl, Map<Integer,Integer> fetchMap) {
        for(MenuNode treeNode:treeNodes){
            Menu sysMenuExt = (Menu)treeNode.getInfo();
            String menuUrl = sysMenuExt.getUrl();
            if(sysMenuExt.getParentId()!=null && sysMenuExt.getParentId()!=0){
                fetchMap.put(treeNode.getId(),sysMenuExt.getParentId());
            }
            if(treeNode.getSubNode()==null || treeNode.getSubNode().size()==0) {
                if (menuUrl.endsWith(".page")) {
                    int index = menuUrl.lastIndexOf(".page");
                    menuUrl = menuUrl.substring(0, index);
                }
                if (currentUrl.startsWith(menuUrl)) {
                    return sysMenuExt.getId();
                }
            }else {
                Integer id = fetch(treeNode.getSubNode(), currentUrl, fetchMap);
                if(id != null){
                    return id;
                }
            }
        }
        return null;
    }


}
